# -*- coding: utf-8 -*-
import base64
import json
import time
from collections import OrderedDict
from datetime import datetime

import requests
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5

from common.bankcard import db as bank_db
from common.bankcard.model import BANK_DCT
from common.mch import handler as mch_handler
from common.mch.db import get_account
from common.timer import TIMER_EVENT_TYPE
from common.timer.handler import submit_notify_event
from common.utils import track_logging
from common.utils import tz
from common.withdraw import db as withdraw_db
from common.withdraw.model import WITHDRAW_ORDER_STATUS

_LOGGER = track_logging.getLogger('withdraw')

# 双乾网络代付
APP_CONF = {
    '202488': {
        'API_KEY': '({ycDnnL',
        'GATEWAY': 'https://df.95epay.cn/merchant/numberPaid.action',
        'QUERY_GATEWAY': 'https://df.95epay.cn/merchant/numberPaidQuery.action',
        'pri_key': """-----BEGIN RSA PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMKK22lVW0sU/A1M
9ToxUXFbfdl2zdEfNlKhRRplZ+wEdIIuLzoTsbw5C3F/QAzxHpIpc3Il55kqwR0t
3bobEjWVaF5oUzgtL6X5WVshSxX7tZHUsIPERAbdindZ/XYE65hoWZKdXEYoC9dR
sgMV2M6kHw0olQwiJfzMWwq/St0JAgMBAAECgYBIC0BB+9g5L+Y/zrYp/MWaYzVx
6StDPHnTk+GRauhXYTb8VroqmcyCVeXE/EjuAgU+P5d/OEZSVKD7e1bXatsM04k0
37qrv8Vrnl8SUFwTf7Fif/4Y3OygfWOkgHYcgD8v84dssoeaWph9U1lPbn5cZwuU
7W/mMui0Q/z8rKhPYQJBAOcqBehBjrneqGWbwVd+6kt4RE/cZRunsTNp7Bpi+PDF
omDlh4/qxYj7LdsZMK9XaWsrTh1N+D/RqeM66BBB9EUCQQDXcZVlAfNt8hYHkk30
QnqBawly2TdJuera9oWX99lu6BWaLr2L2PKqDBXAMbesgRHLRjCSbldXMRTGjpu3
Gqv1AkEAo4E6ymvMWzXdYHlJyOxxJk576wzVyzjSgq4yHPvSXuM7llPjje0eKWSY
q7dmky891lq8Fsg2hlVzV9EroYw1DQJAbeqJKcthAsrr6lj+ZIw2LCkL3QhtaLPt
2mDDr9DHognOW6dVFTBOPeuEfVXgO6ZuCaN5zHt3HAjybIr9buGwsQJAMeBClNiM
YtHbI7GSMToSTm8UeEzNOWnlQeWVOwQjG2GlyjdiC1ArgnIWSzqdaA3Kyx100UZL
9CsHzxSbPSYquw==
-----END RSA PRIVATE KEY-----""",
        'third_pub': '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCR2eKff00xJwM21K4z7JyWx1Rv
ovJCo7hjxyIfULbUteyw3eH+/x9JEbug4ck/xw6oRsXPXMq8EGHAGMuU7mgkMU++
rFhXn9Q33qOCT5smXAfy472qQQuhuDJQOKJUMRC6d+A33QXH0no9hjR+7gYSDzdi
qNxmGfftQW7QDIvoLwIDAQAB
-----END PUBLIC KEY-----'''
    },
}


def _get_api_key(app_id):
    return APP_CONF[app_id]['API_KEY']


def _get_gateway(app_id):
    return APP_CONF[app_id]['GATEWAY']


def _get_query_gateway(app_id):
    return APP_CONF[app_id]['QUERY_GATEWAY']


def _get_pri_key(mch_id):
    return APP_CONF[mch_id]['pri_key']


def _get_third_pub_key(mch_id):
    return APP_CONF[mch_id]['third_pub']


def _gen_sign(message, the_key):
    key = RSA.importKey(the_key)
    h = SHA.new(message)
    signer = Signature_pkcs1_v1_5.new(key)
    signature = signer.sign(h)
    return base64.b64encode(signature)


def _verify_sign(data, signature, key):
    key = RSA.importKey(key)
    h = SHA.new(data)
    verifier = Signature_pkcs1_v1_5.new(key)
    if verifier.verify(h, base64.b64decode(signature)):
        return True
    return False


# 商户号&发起时间&总金额&笔数&批次号&内容
def generate_rsa_sign_str(parameter):
    s = 'merno=%s&time=%s&totalAmount=%s&num=%s&batchNo=%s&content=%s' % (
        parameter['merno'].encode('utf8'), parameter['time'].encode('utf8'),
        parameter['totalAmount'].encode('utf8'), parameter['num'].encode('utf8'),
        parameter['batchNo'].encode('utf8'), parameter['content'].encode('utf8'))
    _LOGGER.info("shuangqian_withdraw sign str: %s", s)
    return s


# 商户号&批次号&订单号
def generate_query_rsa_sign_str(parameter):
    s = 'merno=%s&batchNo=%s&orderNo=%s' % (
        parameter['merno'].encode('utf8'), parameter['batchNo'].encode('utf8'),
        parameter['orderNo'].encode('utf8'))
    _LOGGER.info("shuangqian_withdraw query sign str: %s", s)
    return s


def create_order(order, channel):
    try:
        app_id = channel.appid
        mch = get_account(order.mch_id)
        ts = int(time.time())
        dt = tz.utc_to_local(datetime.fromtimestamp(ts)).strftime('%Y%m%d%H%M%S')
        # 开户名|开户行代码|卡号|卡类别|金额|订单号|地级市代码
        # 卡类别：1:个人网银（借记卡），2:企业，3:信用卡(秒付支持)
        content = '%s|%s|%s|%s|%s|%s|%s' % (
            order.pay_account_username, BANK_DCT[order.pay_account_bank],
            order.pay_account_num, '1', order.amount,
            '_'.join([str(mch.name), str(order.id)]), '000'
        )
        parameter_dict = OrderedDict((
            ("merno", app_id),
            ('time', dt),
            ("totalAmount", '%.2f' % float(order.amount)),
            ('num', '1'),
            ("batchNo", '_'.join([str(mch.name), str(order.id)])),
            ('content', content),
        ))
        sign_str = generate_rsa_sign_str(parameter_dict)
        parameter_dict['signature'] = _gen_sign(sign_str, _get_pri_key(app_id))
        # 先设置为三方未知状态
        order.status = WITHDRAW_ORDER_STATUS.THIRD_UNKNOWN
        order.third_type = channel.id
        order.save()
        _LOGGER.info('shuangqian_withdraw create data: %s', json.dumps(parameter_dict))
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        response = requests.post(_get_gateway(app_id), data=parameter_dict, headers=headers, timeout=5)
        _LOGGER.info('shuangqian_withdraw create rsp: %s, %s', response.text, order.id)
        data = json.loads(response.text)
        status = data.get('status', None)
        if status == 'success':
            order.status = WITHDRAW_ORDER_STATUS.THIRD
            order.extra_info = response.content
            order.save()
            return True
        else:
            order.detail = data.get('error', '')
            order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
            order.extra_info = response.content
            order.save()
            return False
    except Exception, e:
        _LOGGER.info('shuangqian_withdraw create order fail: %s, %s', e, order.id)
        return False


def check_notify_sign(request, app_id):
    # 对方没有回调接口。
    pass


def query_order(app_id, pay_id):
    parameter_dict = {
        "merno": app_id,
        "batchNo": app_id + '_' + str(pay_id),
        "orderNo": app_id + '_' + str(pay_id),
    }
    sign_str = generate_query_rsa_sign_str(parameter_dict)
    parameter_dict['signature'] = _gen_sign(sign_str, _get_pri_key(app_id))
    _LOGGER.info('shuangqian_withdraw create data: %s', json.dumps(parameter_dict))
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    response = requests.post(_get_gateway(app_id), data=parameter_dict, headers=headers, timeout=5)
    _LOGGER.info('shuangqian_withdraw query rsp, %s', response.text)
    if response.status_code != 200:
        return
    order = withdraw_db.get_order(pay_id)
    data = json.loads(response.text)
    # 单笔状态（1:已提交,2:已处理,3:已退回,4.已出账）
    # 我们暂时没有批量，所以取list第一个元素
    if str(data['contents'][0]['state']) != '4':
        return
    order.status = WITHDRAW_ORDER_STATUS.DONE
    order.extra_info = response.text
    order.save()
    if data['contents'][0].get('cardNumber', None):
        bank_db.update_real_balance(data['contents'][0].get('cardNumber'), data['amount'])
    _LOGGER.info("shuangqian_withdraw success mch_id: %s, order_id: %s", order.mch_id, order.id)
    notify_success, _ = mch_handler.notify_mch_withdraw(order)
    if not notify_success:
        submit_notify_event(order, TIMER_EVENT_TYPE.MCH_WITHDRAW_NOTIFY)
